﻿using Common.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CDService
{
    class IAQIHelper
    {
        private static readonly ILog Logger = LogManager.GetLogger(typeof(IAQIHelper));
        private static float[] IAQILimit = { 0, 50, 100, 150, 200, 300, 400, 500 };
        private static float[] SO2Limit = { 0, 150, 500, 650, 800};
        private static float[] NO2Limit = { 0, 100, 200, 700, 1200, 2300, 3090, 3840 };
        private static float[] COLimit = { 0, 5, 10, 35, 60, 90, 120, 150 };
        private static float[] O3Limit = { 0, 160, 200, 300, 400, 800, 1000, 1200 };
        private static float[] PM10Limit = { 0, 50, 150, 250, 350, 420, 500, 600 };
        private static float[] PM25Limit = { 0, 35, 75, 115, 150, 250, 350, 500 };


        public static double Calc(float Concentration, string type) {
            //当污染物物浓度超过最大值，直接返回500
            float[] aqiLimit = GetAQILimint(type);
            if (Concentration > aqiLimit[aqiLimit.Length - 1]) {
                return 500;
            }

            return CalcIAQL(Concentration, type);
        }

        /// <summary>
        /// 计算空气质量分指数
        /// </summary>
        /// <returns></returns>
        private static double CalcIAQL(float concentration, string type)
        {
            float Conclow = 0, Conchigh=0, AQIhigh=0, AQIlow=0;
            int index = GetLimit(concentration, type);

            float[] aqiLimit = GetAQILimint(type);

            if (index == -1)
            {
                index = aqiLimit.Length - 1;
            }
            Conclow = aqiLimit[index - 1];
            Conchigh = aqiLimit[index];
            AQIlow = IAQILimit[index - 1];
            AQIhigh = IAQILimit[index];


            float iaqi= ((concentration - Conclow) / (Conchigh - Conclow)) * (AQIhigh - AQIlow) + AQIlow;
            double linear = 0;
            if ("CO".Equals(type))
            {
                linear = Math.Round(iaqi, 1);
            }
            else {
                linear = Math.Round(iaqi, 0);
            }
            Logger.Info(string.Format("type:{0} 浓度：{1} AQI:{2}", type, concentration, linear));
            return linear;
        }

        private static int GetLimit(float concentration, string type)
        {
            float[] aqiLimit= GetAQILimint(type);
           
            int index = -1;
            for (int i = 0; i < aqiLimit.Length; i++)
            {
                if (concentration < aqiLimit[i])
                {
                    index = i;
                    break;
                }
            }
            return index;
        }

        private static float[] GetAQILimint(string type) {
            switch (type)
            {
                case "SO2":
                    return SO2Limit;
                case "NO2":
                    return NO2Limit;
                case "CO":
                    return COLimit;
                case "O3":
                    return O3Limit;
                case "PM10":
                    return PM10Limit;
                case "PM25":
                    return PM25Limit;
                default:
                    return null;
            }
        }
    }
}
